import React, { PureComponent } from 'react';
import { Resizable } from 'react-resizable';
import { Table, Alert, Divider } from 'antd';

import TableConfig from '@/components/TableConfig';
import styles from './index.less';

const initTotalList = columns => {
  const totalList = [];
  columns.forEach(column => {
    if (column.needTotal) {
      totalList.push({ ...column, total: 0 });
    }
  });
  return totalList;
};

const ResizeableTitle = props => {
  const { onResize, width, ...restProps } = props;
  if (!width) {
    return <th {...restProps} />;
  }
  return (
    <Resizable
      width={width}
      height={0}
      onResize={onResize}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  );
};

class StandardTable extends PureComponent {
  constructor(props) {
    super(props);
    const { data = {} } = props;
    const { columns } = data;
    this.state = {
      columns,
      selectedRowKeys: [],
      needTotalList: initTotalList(columns),
      drawerVisible: false,
    };
  }

  static getDerivedStateFromProps(nextProps) {
    // clean state
    const { data = {}, selectedRows } = nextProps;
    if (selectedRows && selectedRows.length === 0) {
      const { columns } = data;
      return {
        selectedRowKeys: [],
        needTotalList: initTotalList(columns),
      };
    }
    return null;
  }

  handleResize = index => (e, { size }) => {
    this.setState(({ columns }) => {
      const nextColumns = [...columns];
      nextColumns[index] = { ...nextColumns[index], width: size.width };
      return { columns: nextColumns };
    });
  };

  handleDrawerOpen = () => this.setState({ drawerVisible: true });

  handleDrawerClose = () => this.setState({ drawerVisible: false });

  handleConfigChange = config => {
    const { columns } = config;
    this.setState({ columns });
  };

  handleRowSelectChange = (selectedRowKeys, selectedRows) => {
    let { needTotalList } = this.state;
    needTotalList = needTotalList.map(item => ({
      ...item,
      total: selectedRows.reduce((sum, val) => sum + parseFloat(val[item.dataIndex]) || 0, 0),
    }));
    const { onSelectRow } = this.props;
    onSelectRow && onSelectRow(selectedRows, selectedRowKeys);
    this.setState({ selectedRowKeys, needTotalList });
  };

  cleanSelectedKeys = () => this.handleRowSelectChange([], []);

  renderSelectAlert = () => {
    const { selectedRowKeys, needTotalList } = this.state;
    const message = (
      <>
        已选择 <a style={{ fontWeight: 600 }}>{selectedRowKeys.length}</a> 项&nbsp;&nbsp;
        {needTotalList.map(item => (
          <span style={{ marginLeft: 8 }} key={item.dataIndex}>
            {item.title}&nbsp;总计&nbsp;
            <span style={{ fontWeight: 600 }}>
              {item.render ? item.render(item.total) : item.total}
            </span>
          </span>
        ))}
        <a onClick={this.cleanSelectedKeys} style={{ marginLeft: 24 }}>
          清空
        </a>
        <Divider type="vertical" />
        <a onClick={this.handleDrawerOpen}>配置</a>
      </>
    );
    return (
      <div className={styles.tableAlert}>
        <Alert type="info" showIcon message={message} />
      </div>
    );
  };

  render() {
    const { columns, selectedRowKeys, drawerVisible } = this.state;
    const { data = {}, selectedRows, rowKey, ...rest } = this.props;
    const { list = [], pagination } = data;

    const tableColumns = columns
      .filter(col => !col.hidden)
      .map((column, i) => ({
        ...column,
        onHeaderCell: col => ({ width: col.width, onResize: this.handleResize(i) }),
      }));

    const rowSelection = selectedRows
      ? {
          selectedRowKeys,
          onChange: this.handleRowSelectChange,
          getCheckboxProps: record => ({ disabled: record.disabled }),
        }
      : null;

    return (
      <div className={styles.standardTable}>
        {selectedRows && this.renderSelectAlert()}
        <Table
          size="middle"
          bordered
          components={{ header: { cell: ResizeableTitle } }}
          columns={tableColumns}
          dataSource={list}
          rowKey={rowKey || 'key'}
          rowSelection={rowSelection}
          pagination={{ showSizeChanger: true, showQuickJumper: true, ...pagination }}
          {...rest}
        />
        <TableConfig
          config={{ columns }}
          drawerVisible={drawerVisible}
          onDrawerClose={this.handleDrawerClose}
          onConfigChange={this.handleConfigChange}
        />
      </div>
    );
  }
}

export default StandardTable;
